package com.XinYun.Library.modules.commons.filters;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.XinYun.Library.modules.commons.BasicJson;
import com.XinYun.Library.modules.commons.ReturnCodes.Impl.ReturnCodes;
import com.XinYun.Library.utils.JWTUtils;
import org.apache.poi.ss.formula.functions.T;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

@WebFilter("/*")
public class BasicFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) servletResponse;
        HttpServletRequest req = (HttpServletRequest) servletRequest;

        /*过滤链*/
        try{
            /*放行前操作*/
            //设置编码
            encoding(req,res);
            //允许跨域
            acceseField(req,res);
            //登录拦截
            loginVerify(req,res);
            //放行
            filterChain.doFilter(req,res);
            /*返回操作*/
            //统一响应
            crossError(res);
        }catch (RuntimeException e){
            //返回
            return;
        }
    }

    private void encoding(ServletRequest request, ServletResponse response){
        try{
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
        }catch (Exception e){
            throw new RuntimeException("拦截");
        }
    }

    private void acceseField(HttpServletRequest request, HttpServletResponse response){

        try{
            response.addHeader("Access-Control-Allow-Origin","*");
            //允许所有方式
            response.addHeader("Access-Control-Allow-Methods","*");
            response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Access-Token,Accept");
            response.addHeader("Access-Control-Max-Age","3600");
            response.addHeader("Access-Control-Allow-Credentials","true");
            //解决预请求问题
            if ("OPTIONS".equals(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
            }
        }catch (Exception e){
            throw new RuntimeException();
        }
    }

    private void loginVerify(HttpServletRequest request, HttpServletResponse response) throws IOException{
        //默认放行请求
        String[] servlets = {"LoginServlet","VerifyServlet","RegisterServlet"};
        //获得接口名
        String methodName = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/")+1);
        if(!isContain(methodName,servlets)){
            //验证jwt
            String jwt = request.getHeader("token");
            //验证是否为null或空
            if(StrUtil.isEmpty(jwt) || !verifyJwt(jwt)) {
                //返回未登录
                BasicJson<Object> json = new BasicJson<>();
                json.setReturnCM(ReturnCodes.UNLOGIN);
                //返回信息
                response.setContentType("text/json;charset=utf-8");
                response.getWriter().write(JSONUtil.toJsonStr(json));
                throw new RuntimeException();
            }
        }
    }

    private void crossError(HttpServletResponse response){
        //不使用状态码，使用业务码表示更多范围
        response.setStatus(200);
    }

    /**
     * 验证jwt
     * @return
     */
    private boolean verifyJwt(String token){
        try{
            //解析
            JWTUtils.parseJWT(token);
            return true;
        }catch (Exception e){
            //返回false
            return false;
        }
    }

    private <T> boolean isContain(T obj, T... objs){
        for (T t : objs) {
            if(t.equals(obj)){
                return true;
            }
        }
        return false;
    }
}
